<template>
    <div>
        <div class="api-head">
            <label>API版本</label>
            <Select v-model="currentApi.id" @on-change="selectVersions" style="width: 200px">
                <Option v-for="item in versionNameSelect" :value="item.id" :key="item.id">{{ item.versionName }}</Option>
            </Select>

            <label style="margin-left: 16px">basePath</label>
            <Input style="width: 200px" v-model="currentApi.basePath" readonly></Input>

            <div class="api-btns">
                <Button type="primary" @click="addVersion">新增</Button>
                <Button type="info" @click="updateVersion">修改</Button>
                <Button type="error" @click="deleteVersion">删除</Button>
            </div>

            <Input style="width: 200px; margin-left: auto" icon="search" v-model="searchUrl" placeholder="地址"></Input>
        </div>
        <div class="api-list">
            <div v-for="item in apiDataList" :key="item.id">
                <api-detail :api="item" @edit-api="editApi" :searchUrl="searchUrl"></api-detail>
            </div>
        </div>

        <div class="project-plus">
            <Icon type="plus-circled"  class="plus-icon" @click="addApi"></Icon>
        </div>

        <Modal v-model="showVersion"  :title="addFlag?'新增api版本':'新增api版本'">
            <Form ref="apiBaseForm" :model="apiBase" label-position="top" :rules="ruleValidate">
                <Form-item label="版本名" prop="versionName">
                    <Input v-model="apiBase.versionName" placeholder="v1" ></Input>
                </Form-item>
                <Form-item label="basePath" prop="basePath">
                    <Input v-model="apiBase.basePath" placeholder="/demo"></Input>
                </Form-item>
            </Form>
            <div slot="footer">
                <Button type="text" @click="showVersion = false">取消</Button>
                <Button type="primary"  @click="saveApiVersion">确定</Button>
            </div>
        </Modal>

        <Modal
                v-model="showAddApi"
                width="680px"
                :title="addFlag?'添加API':'修改API'">
            <Form ref="apiForm" :model="apiDetail" label-position="right" :rules="apiValidate" :label-width="75">
                <Form-item label="uri" prop="uri" >
                    <Input v-model="apiDetail.uri" ></Input>
                </Form-item>
                <Form-item label="请求方法" prop="requestMethod" >
                    <Select v-model="apiDetail.requestMethod" placeholder="请选择" >
                        <Option  v-for="item in requestMethodList" :value="item" :key="item" >{{ item }}</Option>
                    </Select>
                </Form-item>
                <Form-item label="概述" prop="summary">
                    <Input v-model="apiDetail.summary" ></Input>
                </Form-item>
                <Form-item label="描述" prop="description">
                    <Input v-model="apiDetail.description" type="textarea" :autosize="{minRows: 2,maxRows: 5}" placeholder="请输入..." ></Input>
                </Form-item>
                <Form-item label="标签" prop="tag">
                    <Input v-model="apiDetail.tag" ></Input>
                </Form-item>
                <Form-item label="参数">
                    <Table :columns="apiParamColumn" :data="apiDetail.apiParams" size="small"></Table>
                    <Button type="primary" style="margin-top: 20px;" size="small" @click="addProp">新增参数</Button>
                </Form-item>
                <Form-item label="返回值" prop="responseObjName" >
                    <Select  v-model="apiDetail.responseObjName" placeholder="请选择" placement="top">
                        <Option v-for="(child,index) in resDtoList" :value="child" :key="index" >{{child}}</Option>
                    </Select>
                </Form-item>
                <Form-item label="泛型类型"  prop="responseObjGenericType" v-if="apiDetail.responseObjName === 'ResultPageDTO'">
                    <Select placeholder="请选择" v-model="apiDetail.responseObjGenericType" placement="top">
                        <Option v-for="item in propTypeList" :value="item" :key="item">{{ item }}</Option>
                    </Select>
                </Form-item>
                <Form-item label="泛型格式" prop="responseObjGenericFormat" v-if="apiDetail.responseObjName  === 'ResultPageDTO'">
                    <Select placeholder="请选择"  v-model="apiDetail.responseObjGenericFormat" placement="top">
                        <!--基础类型下的内容-->
                        <Option v-for="(item,index) in baseTypeList.base.data" :value="item" :key="index" v-if="apiDetail.responseObjGenericType === 'base'">{{ item }}</Option>

                        <Option-group label="基本类型" v-if="apiDetail.responseObjGenericType === 'array'">
                            <Option v-for="(item,index) in baseTypeList.base.data" :value="'base.'+item" :key="index" >{{ item }}</Option>
                        </Option-group>
                        <Option-group label="DTO实体" v-if="apiDetail.responseObjGenericType === 'array'" >
                            <div v-for="item in baseTypeList.dto.data">
                                <Option v-for="(child,index) in item.data" :value="'dto.'+(item.packName == 'default'?'':item.packName + '.') +child.className" :key="index" >
                                    {{(item.packName == 'default'?'':item.packName + '.') +child.className}}
                                </Option>
                            </div>
                        </Option-group>
                        <Option-group label="PO实体" v-if="apiDetail.responseObjGenericType === 'array'" >
                            <div v-for="item in baseTypeList.po.data">
                                <Option v-for="(child,index) in item.data" :value="'po.'+item.packName + '.' +child.className" :key="index" >
                                    {{item.packName + '.' +child.className}}
                                </Option>
                            </div>
                        </Option-group>

                        <Option  v-if="apiDetail.responseObjGenericType === 'dto'" v-for="(child,index) in dtoList" :value="child" :key="index"></Option>

                        <Option  v-if="apiDetail.responseObjGenericType === 'po'" v-for="(child,index) in poList" :value="child" :key="index" ></Option>
                    </Select>
                </Form-item>
            </Form>
            <div slot="footer">
                <Button type="text" @click="showAddApi = false">取消</Button>
                <Button type="primary"  @click="saveApi">确定</Button>
            </div>
        </Modal>

        <Modal
                v-model="showParam"
                :title="addParamFlag?'新增参数':'修改参数'">
            <Form ref="paramForm" label-position="top" :model="paramData" :rules="paramValidate">
                <Form-item label="名称" prop="name">
                    <Input v-model="paramData.name"></Input>
                </Form-item>
                <Form-item label="形式" prop="form">
                    <Select  placeholder="请选择" v-model="paramData.form">
                        <Option  v-for="item in parametricForm" :value="item" :key="item">{{ item }}</Option>
                    </Select>
                </Form-item>
                <Form-item label="描述" prop="description">
                    <Input v-model="paramData.description" type="textarea" :autosize="{minRows: 2,maxRows: 5}" placeholder="请输入..." ></Input>
                </Form-item>
                <Form-item label="是否必需" prop="isRequired">
                    <Radio-group v-model="paramData.isRequired">
                        <Radio label="0">否</Radio>
                        <Radio label="1">是</Radio>
                    </Radio-group>
                </Form-item>
                <Form-item label="类型" prop="type" v-if="propTypeList.length > 0">
                    <Select v-model="paramData.type" >
                        <Option v-for="item in propTypeList" :value="item" :key="item">{{ item }}</Option>
                    </Select>
                </Form-item>
                <Form-item label="格式" prop="format" v-if="propTypeList.length > 0">
                    <Select placeholder="请选择"  v-model="paramData.format">
                        <!--基础类型下的内容-->
                        <Option v-for="(item,index) in baseTypeList.base.data" :value="item" :key="index" v-if="paramData.type === 'base'">{{ item }}</Option>

                        <Option-group label="基本类型" v-if="paramData.type === 'array'">
                            <Option v-for="(item,index) in baseTypeList.base.data" :value="'base.'+item" :key="index" >{{ item }}</Option>
                        </Option-group>
                        <Option-group label="DTO实体" v-if="paramData.type === 'array'">
                            <div v-for="item in baseTypeList.dto.data">
                                <Option v-for="(child,index) in item.data" :value="'dto.'+(item.packName === 'default'?'':item.packName + '.') +child.className" :key="index" >
                                    {{(item.packName === 'default'?'':item.packName + '.') +child.className}}
                                </Option>
                            </div>
                        </Option-group>
                        <Option-group label="PO实体" v-if="paramData.type === 'array'">
                            <div v-for="item in baseTypeList.po.data">
                                <Option v-for="(child,index) in item.data" :value="'po.'+item.packName + '.' +child.className" :key="index" >
                                    {{item.packName + '.' +child.className}}
                                </Option>
                            </div>
                        </Option-group>

                        <Option v-for="(child,index) in dtoList" :value="child" :key="index" v-if="paramData.type === 'dto'"></Option>

                        <Option v-for="(child,index) in poList" :value="child" :key="index" v-if="paramData.type === 'po'"></Option>
                    </Select>
                </Form-item>
            </Form>
            <div slot="footer">
                <Button type="text" @click="showParam = false">取消</Button>
                <Button type="primary"  @click="saveParam">确定</Button>
            </div>
        </Modal>
    </div>
</template>

<script>
    import apiDetail from './apiDetail';
    import paramExpand from './apiParamExpand';
    export default {
        data(){
          return {
              searchUrl: '',
              requestMethodList: ['GET', 'POST', 'PUT', 'DELETE'],
              parametricForm: ['header', 'query', 'path', 'body', 'cookie'],
              propTypeList: [],
              baseTypeList: {
                  base:{
                      data: []
                  },
                  dto:{
                      data: []
                  },
                  po:{
                      data: []
                  },
                  array:{
                      data: []
                  }
              },
              dtoList: [],
              poList: [],
              versionNameSelect: [],
              apiDataList: [],
              showVersion: false,
              showAddApi: false,
              showParam: false,
              ruleValidate: {
                  versionName: [
                      {required: true, message: '版本名不能为空', trigger: 'blur'},
                      {pattern: /^v\d+$/, message: '版本名格式不正确，应为“v”+数字', trigger: 'blur'}
                  ],
                  basePath: [
                      {required: true, message: 'BasePath不能为空', trigger: 'blur'},
                      {pattern: /^(\/[^A-Z]+|\/)$/, message: '请以"/"开头,不要填写大写字母', trigger: 'blur'}
                  ]
              },
              apiValidate:{
                  uri: [
                      { required: true, message: 'uri不能为空', trigger: 'blur' },
                      {pattern :/^\//,message: '请以"/"开头', trigger: 'change'}
                  ],
                  requestMethod: [
                      { required: true, message: '请求方法不能为空', trigger: 'change' },
                  ],
                  summary: [
                      { required: true, message: '概述不能为空', trigger: 'blur' },
                  ],
                  responseObjName: [
                      { required: true, message: '返回值不能为空', trigger: 'blur' },
                  ]
              },
              paramValidate:{
                  name: [
                      { required: true, message: '参数名不能为空', trigger: 'blur' },
                      {pattern :/^([a-z]+|[a-z][a-zA-Z]+)$/,message: '请使用驼峰命名法命名，不要添加特殊字符', trigger: 'change'}
                  ],
                  type: [
                      { required: true, message: '类型不能为空', trigger: 'change' },
                  ],
                  format: [
                      { required: true, message: '格式不能为空', trigger: 'change' },
                  ],
                  form: [
                      { required: true, message: '型式不能为空', trigger: 'change' }
                  ]
              },
              apiBase: {
                  versionName: '',
                  projectId: this.id,
                  basePath: '',
                  id: ''
              },
              currentApi: {
                  versionName: '',
                  projectId: this.id,
                  basePath: '',
                  id: ''
              },
              addFlag: true,
              addParamFlag: true,
              apiDetail: {
                  id: '',
                  apiBaseId: '',
                  apiParams: [],
                  description: '',
                  requestMethod: '',
                  responseObjGenericType: '',
                  responseObjGenericFormat: '',
                  responseObjName: '',
                  summary: '',
                  tag: '',
                  uri: ''
              },
              paramData: {
                  name: '',
                  form: '',
                  description: '',
                  isRequired: '0',
                  type: '',
                  format: [],
                  arrayType: ''
              },
              currentParamIndex: 0,
              apiParamColumn: [
                  {
                      type: 'expand',
                      width: 50,
                      render: (h, params) => {
                          return h(paramExpand, {
                              props: {
                                  row: params.row
                              }
                          });
                      }
                  },
                  {
                      title: '名称',
                      key: 'name'
                  },
                  {
                      title: '形式',
                      key: 'form'
                  },
                  {
                      title: '描述',
                      key: 'description'
                  },
                  {
                      title: '操作',
                      key: 'operation',
                      render: (h, params) => {
                          return h('div', {}, [
                              h('Button', {
                                  props: {
                                      type: 'primary',
                                      size: 'small',
                                  },
                                  style: {
                                      marginRight: '5px'
                                  },
                                  on: {
                                      click: () => {
                                          this.currentParamIndex = params.index;
                                          this.showParam = true;
                                          this.addParamFlag = false;
                                          this.paramData = params.row;
                                      }
                                  },
                              }, '修改'),
                              h('Button', {
                                  props: {
                                      size: 'small',
                                      type: 'error',
                                  },
                                  on: {
                                      click: () => {
                                          this.deleteParam(params.index);
                                      }
                                  }
                              }, '删除'),
                          ]);
                      }
                  }],
              resDtoList:[]
          };
        },
        components:{
            apiDetail,
            paramExpand
        },
        props:{
            id: String
        },
        created(){
            this.getApiVersion();
            this.getBaseTypeList();   //获取版本信息及类型数据
            this.getResponseObjName();
        },
        methods:{
            getBaseTypeList (){
                this.$http.get('/codegen/api/v1/project/'+this.id+'/data_type').then((response)=>{
                    this.baseTypeList = response.data;
                    for (let key in response.data) {
                        if (typeof(response.data[key]) === 'object') {
                            this.propTypeList.push(key);
                        }
                    }
                    response.data.dto.data.forEach((item) => {
                        item.data.forEach((dto) => {
                            this.dtoList.push((item.packName === 'default'?'':item.packName + '.') +dto.className);
                        });
                    });
                    response.data.po.data.forEach((item) => {
                        item.data.forEach((child) => {
                            this.poList.push(item.packName + '.' +child.className);
                        });
                    });
                });
            },
            //获取返回值数据
            getResponseObjName(){
                this.$http.get('/codegen/api/v1/project/'+ this.id +'/dto_po').then((response) => {
                    if (response.data && response.data.dto) {
                        response.data.dto.data.forEach((item) => {
                            item.data.forEach((dto) => {
                                this.resDtoList.push((item.packName === 'default'?'':item.packName + '.') +dto.className);
                            });
                        });
                    }
                });
            },
            getApiVersion(){
                this.$http.get('/codegen/api/v1/apibases/'+ this.id +'/show').then((response) => {
                    this.versionNameSelect = response.data.apiBases;
                    if (this.currentApi.id === '') {
                        this.currentApi.id =  response.data.apiBases[0].id;
                        this.currentApi.basePath =  response.data.apiBases[0].basePath;
                        this.currentApi.versionName =  response.data.apiBases[0].versionName;
                    }
                });
            },
            selectVersions(id){
                this.versionNameSelect.forEach((item)=>{
                    if (item.id === id) {
                        this.currentApi.id = item.id;
                        this.currentApi.basePath = item.basePath;
                        this.currentApi.versionName = item.versionName;
                    }
                });
            },
            addVersion(){
                this.$refs['apiBaseForm'].resetFields();
                this.apiBase.id = null;
                this.showVersion = true;
                this.addFlag = true;
            },
            updateVersion(){
                this.showVersion = true;
                this.addFlag = false;
                this.apiBase = JSON.parse(JSON.stringify(this.currentApi));
            },
            deleteVersion(){
                this.$Modal.confirm({
                    title: '版本名:' + this.currentApi.versionName,
                    content: '<p>确认删除该版本信息吗？</p>',
                    onOk: () => {
                        this.$http.delete('/codegen/api/v1/apibase/'+this.currentApi.id+'/delete').then((response) => {
                            if(response.data.statusCode === '200'){
                                this.getApiVersion();
                                this.$Message.success('删除成功');
                            } else{
                                this.$Message.error('删除失败');
                            }
                        });
                    }
                });
            },
            saveApiVersion(){
                this.$refs['apiBaseForm'].validate((valid) => {
                    if(valid){
                        this.$http.post('/codegen/api/v1/apibase/save', this.apiBase).then((res)=>{
                            if(res.data.statusCode === '200'){
                                this.getApiVersion();
                                this.$Message.success('保存成功');
                                this.showVersion = false;
                            } else{
                                this.$Message.error('删除失败');
                            }
                        });
                    }
                });
            },
            addApi(){
                this.showAddApi = true;
                this.addFlag = true;
                this.$refs['apiForm'].resetFields();
                this.apiDetail.id = null;
                this.apiDetail.apiParams = [];
            },
            addProp(){
                this.showParam = true;
                this.addParamFlag = true;
                this.$refs['paramForm'].resetFields();
                this.paramData.isRequired = '0';
                this.paramData.arrayType = null;
            },
            saveParam(){
                this.$refs['paramForm'].validate((valid) => {
                    if (valid) {
                        if (this.addParamFlag) {
                            this.apiDetail.apiParams.push(this.paramData);
                        } else {
                            this.apiDetail.apiParams[this.currentParamIndex] = this.paramData;
                        }
                        this.showParam = false;
                    }
                });
            },
            deleteParam(index){
                this.apiDetail.apiParams.splice(index, 1);
            },
            saveApi(){
                this.$refs['apiForm'].validate((valid) => {
                    if (valid) {
                        this.$http.post('/codegen/api/v1/apiobj/save', this.apiDetail).then((res)=>{
                            if (res.data.statusCode === '200') {
                                this.$Message.success('保存成功');
                                this.getApiList(this.currentApi.id);
                                this.showAddApi = false;
                            }
                        });
                    }
                });
            },
            getApiList(id){
                this.$http.get('/codegen/api/v1/apiobjs/'+ id + '/show').then((response) => {
                    this.apiDataList = response.data.apiObjs;
                });
            },
            editApi(apiDetail){
                this.showAddApi = true;
                this.addFlag = true;
                this.$refs['apiForm'].resetFields();
                this.apiDetail = JSON.parse(JSON.stringify(apiDetail));
                if (this.apiDetail.responseObjGenericType === 'array') {
                    this.apiDetail.responseObjGenericFormat = apiDetail.responseObjGenericArrayType + '.' + apiDetail.responseObjGenericFormat;
                } else {
                    this.apiDetail.responseObjGenericFormat = apiDetail.responseObjGenericFormat;
                }
                this.$http.get('/codegen/api/v1/apiparams/' + apiDetail.id + '/show').then((response) => {
                    this.apiDetail.apiParams = response.data.apiParams;
                    for (let i = 0; i < response.data.apiParams.length; i++) {
                        if (this.apiDetail.apiParams[i].type === 'array') {
                            this.apiDetail.apiParams[i].format = response.data.apiParams[i].arrayType + '.' + response.data.apiParams[i].format;
                        }
                    }
                });

            }
        },
        watch:{
            'currentApi.id':function (val) {
                this.getApiList(val);
                this.apiDetail.apiBaseId = val;
            },
            'apiDetail.responseObjName': function (val) {
                if(val !== 'ResultPageDTO'){
                    this.apiDetail.responseObjGenericType = '';
                    this.apiDetail.responseObjGenericFormat = '';
                }
            }
        }
    };
</script>

<style scoped lang="scss">
    .api-head{
        display: flex;
        align-items: center;
        margin-bottom: 16px;

        label{
            margin-right: 6px;
        }

        .api-btns{
            margin-left: 16px;
            button{
                margin-right: 8px;
            }
        }
    }

    .project-plus{
        position: fixed;
        right: 16px;
        bottom: 22px;

        .plus-icon{
            font-size: 42px;
            color: #2d8cf0;
            cursor: pointer;
            &:hover{
                color: #57a3f3;
            }
        }
    }
</style>